package com.ll.domain.classbase.biz.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ll.app.api.req.DeleteCourseReqDTO;
import com.ll.base.dto.PageResultDTO;
import com.ll.base.enums.ResultCodeEnum;
import com.ll.base.util.ListUtil;
import com.ll.base.util.ScalarUtil;
import com.ll.dal.po.CoursePO;
import com.ll.dal.po.SignupPO;
import com.ll.domain.classbase.biz.CourseDomainService;
import com.ll.domain.classbase.dto.CourseDTO;
import com.ll.domain.classbase.base.CourseBaseService;
import com.ll.domain.classbase.base.SignupBaseService;
import com.ll.domain.classbase.convert.CourseConvert;
import com.ll.domain.classbase.event.producer.AddCourserEvent;
import com.ll.domain.dingtalk.base.DingTalkMessageBaseService;
import com.ll.domain.dingtalk.base.DingTalkUserBaseService;
import com.ll.domain.user.dto.UserDTO;
import com.ll.app.api.req.AddCourseReqDTO;
import com.ll.app.api.req.PageCourseReqDTO;
import com.ll.domain.classbase.enums.CourseIsNotifyEnum;
import com.ll.domain.classbase.enums.CourseStatusEnum;
import com.ll.domain.classbase.enums.SingupStatusEnum;
import com.ll.domain.dingtalk.utils.AccessTokenUtil;
import com.ll.base.dto.ApiResultDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class CourseDomainServiceImpl implements CourseDomainService {

    private final CourseBaseService courseBaseService;
    private final SignupBaseService signupBaseService;
    private final DingTalkMessageBaseService dingTalkMessageBaseService;
    private final DingTalkUserBaseService dingTalkUserBaseService;
    private final ApplicationEventPublisher applicationEventPublisher;
    @Override
    public PageResultDTO<CourseDTO> page(PageCourseReqDTO pageReq) {
        if(ScalarUtil.isEmpty(pageReq.getStatues())){
            pageReq.setStatues(Arrays.asList(CourseStatusEnum.开始中, CourseStatusEnum.未开始));
        }

        PageResultDTO<CoursePO> page = courseBaseService.page(pageReq);

        PageResultDTO<CourseDTO> result = PageResultDTO.PageBuildDTO(page, CourseConvert::PO2DTO);
        if (ScalarUtil.isNotEmpty(result.getDatas())) {
            List<Long> courseIds = ListUtil.toList(result.getDatas(), CourseDTO::getId);

            List<SignupPO> signupPOS = signupBaseService.queryListByUserAndCourseIds(pageReq.getDingTalkUserId(), courseIds);
            Map<Long, SignupPO> signupPOMap = ListUtil.toMap(signupPOS, SignupPO::getCourseId);
            result.getDatas().forEach(r -> {
                if (signupPOMap.containsKey(r.getId())) {
                    r.setSignupStatusCode(signupPOMap.get(r.getId()).getStatus().ordinal());
                } else {
                    r.setSignupStatusCode(SingupStatusEnum.未报名.ordinal());
                }
            });
        }

        return result;
    }

    @Override
    public List<CourseDTO> list(PageCourseReqDTO pageReq) {
        if(ScalarUtil.isEmpty(pageReq.getStatues())){
            pageReq.setStatues(Arrays.asList(CourseStatusEnum.开始中, CourseStatusEnum.未开始));
        }
        List<CoursePO> list = courseBaseService.list(new LambdaQueryWrapper<CoursePO>().in(CoursePO::getStatus, pageReq.getStatues()));
        return ListUtil.toList(list,CourseConvert::PO2DTO);
    }


    @Override
    public ApiResultDTO add(AddCourseReqDTO courseDTO) {
        String token = AccessTokenUtil.getToken();
        UserDTO userDTO = dingTalkUserBaseService.getByUserId(token, courseDTO.getDingTalkUserId());
        if(userDTO == null){
            return ApiResultDTO.failure(ResultCodeEnum.USER_ERROR.getCode(),
                    "用户获取失败"+ courseDTO.getDingTalkUserId());
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(courseDTO.getStartTime());
        cal.add(Calendar.HOUR_OF_DAY, -8);
        courseDTO.setStartTime( cal.getTime());
        cal.setTime(courseDTO.getEndTime());
        cal.add(Calendar.HOUR_OF_DAY, -8);
        courseDTO.setEndTime(cal.getTime());
        CoursePO coursePO = CourseConvert.addCourseReqDTO2PO(courseDTO);

        //发送钉钉通知
        if(courseDTO.getIsPushMsg() != null && courseDTO.getIsPushMsg()){
            dingTalkMessageBaseService.sendCourseNotify(coursePO);
            coursePO.setIsNotify(CourseIsNotifyEnum.已通知);
        }else{
            coursePO.setIsNotify(CourseIsNotifyEnum.未通知);
        }
        courseBaseService.save(coursePO);

        applicationEventPublisher.publishEvent(new AddCourserEvent(CourseConvert.PO2DTO(coursePO)));

        return ApiResultDTO.success();
    }

    @Override
    public void delete(DeleteCourseReqDTO courseDTO) {
        courseBaseService.removeById(courseDTO.getCourseId());
    }
}
